package cn.com.cym.gamezao.service.xmu.impl;

import cn.com.cym.gamezao.base.BaseImpl;
import cn.com.cym.gamezao.base.BaseRepository;
import cn.com.cym.gamezao.base.SearchPage;
import cn.com.cym.gamezao.entity.SendRes;
import cn.com.cym.gamezao.entity.Sms;
import cn.com.cym.gamezao.entity.xmu.Schedule;
import cn.com.cym.gamezao.quartz.ScheduleJob;
import cn.com.cym.gamezao.repository.xmu.ScheduleRepository;
import cn.com.cym.gamezao.service.SmsService;
import cn.com.cym.gamezao.service.xmu.ScheduleService;
import cn.com.cym.gamezao.util.CommonUtils;
import cn.com.cym.gamezao.util.SMSUtils;
import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class ScheduleImpl extends BaseImpl<Schedule> implements ScheduleService {

    private static final Logger log = LoggerFactory.getLogger(ScheduleImpl.class);

    final ScheduleRepository thisRepository;

    final SmsService smsService;

    @PersistenceContext
    @Resource
    private EntityManager entityManager;

    public ScheduleImpl(ScheduleRepository scheduleRepository,SmsService smsService){
        this.thisRepository = scheduleRepository;
        this.smsService=smsService;
    }


    @Override
    public Schedule update(Schedule schedule, Long id) {
        schedule.setSendStatus(false);
        return super.update(schedule, id);
    }

    @Override
    public Schedule save(Schedule schedule) {
        return super.save(schedule);
    }

    @Override
    public BaseRepository<Schedule, Long> getJpaRepository() {
        return thisRepository;
    }

    @Override
    public Page<Schedule> findByPageable(SearchPage searchPage) {
        String[] sortBy = searchPage.getSortBy().toArray(new String[searchPage.getSortBy().size()]);
        Pageable pageable = PageRequest.of(searchPage.getCurrent()-1, searchPage.getPageSize(), searchPage.getSort(), sortBy);
        Specification<Schedule> specification = new Specification<>() {
            private static final long serialVersionUID = -2661077778894635593L;
            @SneakyThrows
            @Override
            public Predicate toPredicate(Root<Schedule> root,CriteriaQuery<?> query, CriteriaBuilder cb) {
                final Map<String, Field> fieldMap = ReflectUtil.getFieldMap(Schedule.class);
                return cb.and(CommonUtils.pageSet(fieldMap,searchPage,cb,root));
            }
        };
        return this.thisRepository.findAll(specification, pageable);
    }

    @Override
    public boolean sendMessage() {

        final List<Sms> smss = this.smsService.getAll();
        if(smss.isEmpty()){
            log.warn("未找到短信平台相关配置");
            return false;
        }
        final Sms sms = smss.get(0);

        SMSUtils smsUtils=new SMSUtils();

        // 获取明天需要发送的数据
        final List<Schedule> all = this.thisRepository.getByClassDateAndSendStatus(LocalDate.now().plusDays(1),false);
        for(Schedule schedule:all){
            try{
                //封装数据 短信数据
                String message = formatMsg(schedule);
                SendRes sendRes = smsUtils.sendMsg(entityManager,sms, "", message);
                if(!sendRes.isSuccess()){
                    log.warn(schedule.getId()+" 发送消息失败");
                    return false;
                }
                schedule.setSendStatus(true);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    private String formatMsg(Schedule schedule){
        StringBuilder sb=new StringBuilder();
        sb.append(schedule.getTeacher()).append("老师:\n\t\t\t\t您在第").append(schedule.getTerm()).append("学期的第")
                .append(schedule.getCycle()).append("个教学周，（")
                .append(schedule.getClassDate()).append(" 周").append(schedule.getWeek())
                .append("）第").append(schedule.getSection()).append("节，有《")
                .append(schedule.getCourseName()).append("》课程的授课任务，授课内容为《")
                .append(schedule.getTeachContent()).append("》，授课班级为").append(schedule.getTeachObject())
                .append("专业，听课人数").append(schedule.getStuNums()).append("人，上课地点为").append(schedule.getAddress())
                .append("，请您做好上课准备。如果您是首次上课请提前确定好教室位置。辛苦了！");
        log.info(schedule.getTeachTel()+""+sb);
        return "{\""+schedule.getTeachTel()+"\":\""+sb+"\",\""+schedule.getCourseSecretaryTel()+"\":\""+sb+"\",\""+schedule.getAcademicSecretaryTel()
                +"\":\""+sb+"\"}";
    }
}